/***************************************************************************
 *   Copyright (C) 2009 by Zheng Yonglei
 *   zhengyonglei@gmail.com   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/


#include <QFile>
#include <QTextStream>

#include "TrainDataManager.h"

TrainDataManager::TrainDataManager()
{
}

TrainDataManager::~TrainDataManager()
{
}

/*There are 4 inputs
	1. The total test count of word
	2. The interval of last test
	3. The score for test history. For example, below is the test result of a certain word
	<1> Y
	<2> N
	<3> Y
	<4> Y
	<5> N
	<6> N
	<TestID> PassFirstTest
	The score of <6> should be -1 because test 5 was failed.
	The score of <5> should be 2 because test 4 and test 3 was passed.
	4. The complexity of word

	And there is 1 output:
	1. The current test reult: Y(1)/N(0)
 */
//void TrainDataManager::updateTrainDatabase(QString usr, QString fileName)
void TrainDataManager::updateTrainDatabase(QString usr)
{
	createEmptyTrainDataTable(usr);
	scanTestData(usr);

	QString command;
	QTextStream cs(&command);

	QString wordStr;
	QString testDate;
	int testInterval = 0;
	int testCount = 0;
	int testRecordHistoryScore = 0;
	int testWordComplexity = 0;
	bool testResult = false;

	DB.execQuery("BEGIN", QueryT_Write, usr);
	for (	map<int, TestWord>::iterator it = mWordMap.begin();
			it != mWordMap.end();
			it++)
	 {
		 TestWord& word = it->second;
		 wordStr = word.word;
		 int googleSearchCount = word.googleSearchCount;
		 map<QDate, TestRecord>& recordMap = word.getTestRecordMap();
		 vector<int> intv;
		 vector<bool> pass;
		 vector<QString> testDateVect;
		 for ( map<QDate, TestRecord>::iterator record_it = recordMap.begin();
				 record_it != recordMap.end();
				 record_it++)
		 {
			 intv.push_back(record_it->second.getInterval());
			 pass.push_back(record_it->second.passFirst());
			 testDateVect.push_back(record_it->first.toString(DATE_FORMAT));
		 }

		 for (int i=0; i<intv.size(); i++)
		 {
			 testDate = testDateVect[i];
			 testCount = i+1;
			 if (i == 0)
			 {
				 testInterval = 0;
				 testRecordHistoryScore = 0;
			 }
			 else
			 {
				 testInterval = intv[i-1] - intv[i];
				 int history_score_inc;
				 int history_score = 0;
				 if (pass[i-1]) history_score_inc = 1;
				 else history_score_inc = -1;
				 int index = i;
				 while(index > 0)
				 {
					 index--;
					 if (pass[index] == pass[i-1])
						 history_score += history_score_inc;
					 else
						 break;
				 }
				 testRecordHistoryScore = history_score;
			 }

			 testWordComplexity = word.calculateComplexity();

			 //set output
			 if (pass[i])
				 testResult = true;
			 else
				 testResult = false;

			 //trainDataCount++;
			 command.clear();
			 cs<<" insert into test_train_data ( "
					 " test_word, "
					 " test_date, "
					 " test_interval, "
					 " test_count, "
					 " test_record_history_score, "
					 " test_word_self_factor, "
					 " test_result) "
					 " values ( "
					 <<" '"<<wordStr<<"', "
					 <<" '"<<testDate<<"', "
					 <<testInterval<<", "
					 <<testCount<<", "
					 <<testRecordHistoryScore<<", "
					 <<googleSearchCount<<", "
					 <<testResult<<");";
			 DB.execQuery(command, QueryT_Write, usr);
		 }
	 }

	DB.execQuery("COMMIT", QueryT_Write, usr);
}

void TrainDataManager::scanTestData(QString usr)
{
	mWordMap.clear();

	QString command;
	QTextStream cs(&command);
	cs<<" select "
			" words.id, "
			" words.word, "
			" words.google_search_count, "
			" test_records.test_record "
			" from words, test_records "
			" where words.id=test_records.id; ";
	DB.execQuery(command, QueryT_Read, usr);

	for (int i=0; i<DB.getRowCount(); i++)
	{
		int id = DB.getTableValue(i, "id").toInt();
		QString word = DB.getTableValue(i, "word");
		QString testRecord = DB.getTableValue(i, "test_record");
		float googleSearchCount = DB.getTableValue(i, "google_search_count").toFloat();

		mWordMap.insert(make_pair(id, TestWord(id)));
		TestWord& testWord = mWordMap[id];
		testWord.word = word;
		testWord.googleSearchCount = googleSearchCount;
		testWord.setTestRecords(testRecord);
	}
}

void TrainDataManager::createEmptyTrainDataTable(QString usr)
{
	QStringList tbl_test_train_data;
	tbl_test_train_data<<" test_data_id integer primary key autoincrement ";
	tbl_test_train_data<<" test_word text ";
	tbl_test_train_data<<" test_date text ";
	tbl_test_train_data<<" test_interval integer ";
	tbl_test_train_data<<" test_count integer ";
	tbl_test_train_data<<" test_record_history_score integer ";
	tbl_test_train_data<<" test_word_self_factor integer ";
	tbl_test_train_data<<" test_result tinyint ";
	DB.createEmptyTable(usr, "test_train_data", tbl_test_train_data);
}
